package com.molichuxing.services.business.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.molichuxing.framework.exception.BizException;
import com.molichuxing.services.business.dto.response.DealerStoreBizDto;
import com.molichuxing.services.infrastructure.dto.response.StoreDto;
import com.molichuxing.services.property.StoreStatusModifyTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.services.business.dto.request.create.DealerBizCreateDto;
import com.molichuxing.services.business.dto.request.modify.DealerBizModifyDto;
import com.molichuxing.services.business.dto.response.DealerBizDto;
import com.molichuxing.services.business.dto.response.DealerDetailInfoBizDto;
import com.molichuxing.services.business.dto.response.DealerInfoBizDto;
import com.molichuxing.services.business.service.DealerBizService;
import com.molichuxing.services.infrastructure.convertor.Convert;
import com.molichuxing.services.infrastructure.dto.request.create.DealerCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.DealerDetailCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.DealerDetailModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.DealerModifyDto;
import com.molichuxing.services.infrastructure.dto.response.DealerDetailDto;
import com.molichuxing.services.infrastructure.dto.response.DealerDto;
import com.molichuxing.services.infrastructure.service.DealerDetailService;
import com.molichuxing.services.infrastructure.service.DealerService;
import com.molichuxing.services.infrastructure.service.StoreService;
import com.molichuxing.services.property.DealerStatusEnum;
import com.molichuxing.services.property.StoreStatusEnum;

/**
 * <p>
 * 经销商组合 服务实现类
 * </p>
 *
 * @author zph
 * @since 2019-08-12
 */
@Service("dealerBizService")
public class DealerBizServiceImpl implements DealerBizService {


    @Autowired
    DealerService dealerService;
    @Autowired
    DealerDetailService dealerDetailService;
    @Autowired
    StoreService storeService;


    /**
     * 获取经销商信息分页列表
     *
     * @param map      key:status Integer 营业状态
     *                 key:shortName String 经销商名称
     *                 key：regionId Integer 区域ID
     *                 key:startCreateTime LocalDateTime 创建开始时间
     *                 key:endCreateTime LocalDateTime 创建结束时间
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<DealerBizDto> getDealerPage(Map<String, Object> map, Integer pageNum, Integer pageSize) throws Exception {
        Paged<DealerDto> dealerPage = dealerService.getDealerPage(map, pageNum, pageSize);
        if (null == dealerPage) {
            return new Paged<DealerBizDto>();
        }
        List<DealerDto> dealerBeanDtoList = dealerPage.getList();
        if (null == dealerBeanDtoList || dealerBeanDtoList.size() == 0) {
            return new Paged<DealerBizDto>();
        }

        List<Integer> dealerIdList = new ArrayList<>();
        for (DealerDto dealerBeanDto : dealerBeanDtoList) {
            dealerIdList.add(dealerBeanDto.getDealerId());
        }
        Map<Integer, DealerDetailDto> dealerDetailBeanMap = dealerDetailService.getDealerDetailMapByIds(dealerIdList);
        Map<Integer, Integer> storeCountMap = storeService.getStoreCountByIds(dealerIdList);

        List<DealerBizDto> pagedReturnList = getPagedReturnList(dealerBeanDtoList, dealerDetailBeanMap, storeCountMap);
        return new Paged<DealerBizDto>(pagedReturnList, dealerPage.getTotal(), pageSize);
    }

    /**
     * 分页返回list
     *
     * @param dealerBeanDtoList
     * @param dealerDetailBeanMap
     * @param storeCountMap
     * @return
     * @throws Exception
     */
    private List<DealerBizDto> getPagedReturnList(List<DealerDto> dealerBeanDtoList,
                                                  Map<Integer, DealerDetailDto> dealerDetailBeanMap, Map<Integer, Integer> storeCountMap) throws Exception {
        List<DealerBizDto> dealerBizDtoList = Convert.toDealerBizDtoList(dealerBeanDtoList);
        for (DealerBizDto dealerBizDto : dealerBizDtoList) {
            Integer dealerId = dealerBizDto.getDealerId();
            if (dealerDetailBeanMap != null) {
                DealerDetailDto dealerDetailBeanDto = dealerDetailBeanMap.get(dealerId);
                Convert.toDealerBizDto(dealerBizDto, dealerDetailBeanDto);
            }
            Integer storeCount = 0;
            if (storeCountMap != null) {
                storeCount = storeCountMap.get(dealerId);
                if (storeCount == null) {
                    storeCount = 0;
                }
            }
            dealerBizDto.setStoreCount(storeCount);
        }
        return dealerBizDtoList;
    }

    /**
     * 编辑经销商信息
     *
     * @param dealerBizModifyDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyDealer(DealerBizModifyDto dealerBizModifyDto) throws Exception {
        Assert.notNull(dealerBizModifyDto, "编辑经销商信息失败");

        DealerModifyDto dealerModifyDto = Convert.toDealer(dealerBizModifyDto);
        Boolean dealerBoolean = dealerService.modifyDealer(dealerModifyDto);
        if (!dealerBoolean) {
            return false;
        }

        DealerDetailModifyDto dealerDetailModifyDto = Convert.toDealerDetail(dealerBizModifyDto);
        Boolean dealerDetailBoolean = dealerDetailService.modifyDealerDetail(dealerDetailModifyDto);
        if (!dealerDetailBoolean) {
            return false;
        }

        return true;
    }

    /**
     * 添加经销商信息
     *
     * @param dealerBusCreateDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Integer createDealer(DealerBizCreateDto dealerBusCreateDto) throws Exception {
        Assert.notNull(dealerBusCreateDto, "添加经销商信息失败");
        String email = dealerBusCreateDto.getEmail();
        Boolean emailExist = dealerDetailService.getEmailExist(email);
        if (emailExist) {
            throw new BizException("邮箱已存在");
        }

        DealerCreateDto dealerCreateDto = Convert.toDealer(dealerBusCreateDto);
        Integer dealerId = dealerService.createDealer(dealerCreateDto);
        Assert.notNull(dealerId, "添加经销商信息失败");

        DealerDetailCreateDto dealerDetailCreateDto = Convert.toDealerDetail(dealerBusCreateDto);
        dealerDetailCreateDto.setId(dealerId);
        Integer dealerDetail = dealerDetailService.createDealerDetail(dealerDetailCreateDto);
        Assert.notNull(dealerDetail, "添加经销商信息失败");

        return dealerId;
    }

    /**
     * 详情-获取经销商基础信息
     *
     * @param dealerId
     * @return
     */
    @Override
    public DealerInfoBizDto getDealerInfo(Integer dealerId) throws Exception {
        Assert.notNull(dealerId, "获取经销商详情失败");
        DealerDto dealerDto = dealerService.getDealerById(dealerId);
        return Convert.toDealerInfoBizDto(dealerDto);
    }

    /**
     * 详情-获取经销商详情信息
     *
     * @param dealerId
     * @return
     * @throws Exception
     */
    @Override
    public DealerDetailInfoBizDto getDealerDetailInfo(Integer dealerId) throws Exception {
        Assert.notNull(dealerId, "获取经销商详情失败");
        DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(dealerId);
        return Convert.toDealerDetailInfoBizDto(dealerDetailDto);
    }

    /**
     * 编辑经销商状态
     *
     * @param dealerId
     * @param status
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyDealerStatus(Integer dealerId, Integer status) throws Exception {
        Assert.notNull(dealerId, "编辑经销商状态失败");
        Assert.notNull(status, "编辑经销商状态失败");

        DealerDto dealerDto = dealerService.getDealerById(dealerId);
        Assert.notNull(dealerDto, "经销商不存在");
        Integer oldStatus = dealerDto.getStatus();
        if (DealerStatusEnum.CLOSE.getValue() == oldStatus) {
            throw new IllegalArgumentException("经销商终止合作，不允许编辑");
        }

        Boolean dealerBoolean = dealerService.modifyDealerStatus(dealerId, status);
        if (!dealerBoolean) {
            return false;
        }

        if (DealerStatusEnum.CLOSE.getValue() == status) {
            storeService.modifyStoreStatusByDealerId(dealerId, StoreStatusEnum.SUSPENSION.getValue(), StoreStatusModifyTypeEnum.OP.getValue());
        }

        return true;
    }

    /**
     * 经销商门店联动
     *
     * @return
     * @throws Exception
     */
    @Override
    public List<DealerStoreBizDto> getDealerStore(Integer status, Integer type, Integer dealerId, Boolean dealerIsShow) throws Exception {
        List<DealerDto> dealerDtoList = dealerService.getAllDealerList(status, type, dealerId);
        List<StoreDto> storeDtoList = storeService.getAllStoreList(status);
        List<DealerStoreBizDto> dealerBizDtoList = Convert.toDealerBizList(dealerDtoList);
        List<DealerStoreBizDto> storeBizDtoList = Convert.toStoreBizList(storeDtoList);
        Map<Integer, List<DealerStoreBizDto>> storeMap = Convert.toDealerStoreBizDtoMap(storeBizDtoList);
        return Convert.toDealerStoreBizDtoList(dealerBizDtoList, storeMap, dealerIsShow);
    }

    /**
     * 通过门店id获取经销商信息
     *
     * @param storeId
     * @return
     * @throws Exception
     */
    @Override
    public DealerDetailInfoBizDto getDealerByStoreId(Integer storeId) throws Exception {
        if (null == storeId) {
            return null;
        }
        StoreDto storeDto = storeService.getStoreById(storeId);
        if (null == storeDto) {
            return null;
        }
        Integer dealerId = storeDto.getDealerId();

        DealerDetailDto dealerDetailDto = dealerDetailService.getDealerDetailById(dealerId);
        return Convert.toDealerDetailInfoBizDto(dealerDetailDto);
    }


}